home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / rcs5ap1s.lzh / RCSEDIT.C < prev    next >
C/C++ Source or Header  |  1991-01-30  |  24KB  |  883 lines

  1. /*
  2.  *                     RCS stream editor
  3.  */
  4. /**********************************************************************************
  5.  *                       edits the input file according to a
  6.  *                       script from stdin, generated by diff -n
  7.  *                       performs keyword expansion
  8.  **********************************************************************************
  9.  */
  10.  
  11. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  12.    Copyright 1990 by Paul Eggert
  13.    Distributed under license by the Free Software Foundation, Inc.
  14.  
  15. This file is part of RCS.
  16.  
  17. RCS is free software; you can redistribute it and/or modify
  18. it under the terms of the GNU General Public License as published by
  19. the Free Software Foundation; either version 1, or (at your option)
  20. any later version.
  21.  
  22. RCS is distributed in the hope that it will be useful,
  23. but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. GNU General Public License for more details.
  26.  
  27. You should have received a copy of the GNU General Public License
  28. along with RCS; see the file COPYING.  If not, write to
  29. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  
  31. Report problems and direct all questions to:
  32.  
  33.     rcs-bugs@cs.purdue.edu
  34.  
  35. */
  36.  
  37.  
  38. /* $Log: rcsedit.c,v $
  39.  * Revision 5.8  1991/01/30  14:21:32  apratt
  40.  * CI with RCS version 5
  41.  *
  42.  * Revision 5.7  91/01/29  17:45:46  apratt
  43.  * Added AKP_BUGFIXES around my bug fixes
  44.  * 
  45.  * Revision 5.6  91/01/16  15:44:50  apratt
  46.  * This version works passably on the ST.
  47.  * 
  48.  * Revision 5.5  90/12/30  05:07:35  eggert
  49.  * checked in with -k by apratt at 91.01.10.13.15.10.
  50.  * 
  51.  * Revision 5.5  1990/12/30  05:07:35  eggert
  52.  * Fix report of busy RCS files when !defined(O_CREAT) | !defined(O_EXCL).
  53.  *
  54.  * Revision 5.4  1990/11/01  05:03:40  eggert
  55.  * Permit arbitrary data in comment leaders.
  56.  *
  57.  * Revision 5.3  1990/09/11  02:41:13  eggert
  58.  * Tune expandline().
  59.  *
  60.  * Revision 5.2  1990/09/04  08:02:21  eggert
  61.  * Count RCS lines better.  Improve incomplete line handling.
  62.  *
  63.  * Revision 5.1  1990/08/29  07:13:56  eggert
  64.  * Add -kkvl.
  65.  * Fix bug when getting revisions to files ending in incomplete lines.
  66.  * Fix bug in comment leader expansion.
  67.  *
  68.  * Revision 5.0  1990/08/22  08:12:47  eggert
  69.  * Don't require final newline.
  70.  * Don't append "checked in with -k by " to logs,
  71.  * so that checking in a program with -k doesn't change it.
  72.  * Don't generate trailing white space for empty comment leader.
  73.  * Remove compile-time limits; use malloc instead.  Add -k, -V.
  74.  * Permit dates past 1999/12/31.  Make lock and temp files faster and safer.
  75.  * Ansify and Posixate.  Check diff's output.
  76.  *
  77.  * Revision 4.8  89/05/01  15:12:35  narten
  78.  * changed copyright header to reflect current distribution rules
  79.  * 
  80.  * Revision 4.7  88/11/08  13:54:14  narten
  81.  * misplaced semicolon caused infinite loop
  82.  * 
  83.  * Revision 4.6  88/08/09  19:12:45  eggert
  84.  * Shrink stdio code size; allow cc -R.
  85.  * 
  86.  * Revision 4.5  87/12/18  11:38:46  narten
  87.  * Changes from the 43. version. Don't know the significance of the
  88.  * first change involving "rewind". Also, additional "lint" cleanup.
  89.  * (Guy Harris)
  90.  * 
  91.  * Revision 4.4  87/10/18  10:32:21  narten
  92.  * Updating version numbers. Changes relative to version 1.1 actually
  93.  * relative to 4.1
  94.  * 
  95.  * Revision 1.4  87/09/24  13:59:29  narten
  96.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  97.  * warnings)
  98.  * 
  99.  * Revision 1.3  87/09/15  16:39:39  shepler
  100.  * added an initializatin of the variables editline and linecorr
  101.  * this will be done each time a file is processed.
  102.  * (there was an obscure bug where if co was used to retrieve multiple files
  103.  *  it would dump)
  104.  * fix attributed to  Roy Morris @FileNet Corp ...!felix!roy
  105.  * 
  106.  * Revision 1.2  87/03/27  14:22:17  jenkins
  107.  * Port to suns
  108.  * 
  109.  * Revision 4.1  83/05/12  13:10:30  wft
  110.  * Added new markers Id and RCSfile; added locker to Header and Id.
  111.  * Overhauled expandline completely() (problem with $01234567890123456789@).
  112.  * Moved trymatch() and marker table to rcskeys.c.
  113.  * 
  114.  * Revision 3.7  83/05/12  13:04:39  wft
  115.  * Added retry to expandline to resume after failed match which ended in $.
  116.  * Fixed truncation problem for $19chars followed by@@.
  117.  * Log no longer expands full path of RCS file.
  118.  * 
  119.  * Revision 3.6  83/05/11  16:06:30  wft
  120.  * added retry to expandline to resume after failed match which ended in $.
  121.  * Fixed truncation problem for $19chars followed by@@.
  122.  * 
  123.  * Revision 3.5  82/12/04  13:20:56  wft
  124.  * Added expansion of keyword Locker.
  125.  *
  126.  * Revision 3.4  82/12/03  12:26:54  wft
  127.  * Added line number correction in case editing does not start at the
  128.  * beginning of the file.
  129.  * Changed keyword expansion to always print a space before closing KDELIM;
  130.  * Expansion for Header shortened.
  131.  *
  132.  * Revision 3.3  82/11/14  14:49:30  wft
  133.  * removed Suffix from keyword expansion. Replaced fclose with ffclose.
  134.  * keyreplace() gets log message from delta, not from curlogmsg.
  135.  * fixed expression overflow in while(c=putc(GETC....
  136.  * checked nil printing.
  137.  *
  138.  * Revision 3.2  82/10/18  21:13:39  wft
  139.  * I added checks for write errors during the co process, and renamed
  140.  * expandstring() to xpandstring().
  141.  *
  142.  * Revision 3.1  82/10/13  15:52:55  wft
  143.  * changed type of result of getc() from char to int.
  144.  * made keyword expansion loop in expandline() portable to machines
  145.  * without sign-extension.
  146.  */
  147.  
  148.  
  149. #include "rcsbase.h"
  150.  
  151. libId(editId, "$Id: rcsedit.c,v 5.8 1991/01/30 14:21:32 apratt Exp $")
  152.  
  153. static void keyreplace P((enum markers,const struct hshentry*,FILE*));
  154.  
  155.  
  156. FILE *fcopy;         /* result file descriptor                */
  157. const char *resultfile;  /* result file name                    */
  158. int locker_expansion;     /* should the locker name be appended to Id val?   */
  159. static FILE *fedit;     /* edit   file descriptor                */
  160. static const char *editfile;     /* edit file                    */
  161. static const char *editdir;  /* edit directory                    */
  162. static unsigned long editline; /*fedit line counter; is always #lines+1     */
  163. static long linecorr; /* #adds - #deletes in each edit run.            */
  164.                /*used to correct editline in case file is not rewound after */
  165.                /* applying one delta                                        */
  166.  
  167. #define DIRTEMPNAMES 3
  168. enum maker {notmade, real, effective};
  169. struct buf dirtfname[DIRTEMPNAMES];        /* unlink these when done */
  170. static volatile enum maker dirtfmaker[DIRTEMPNAMES];    /* if these are set */
  171.  
  172.     FILE *
  173. initeditfiles(dir)
  174.     const char *dir;
  175. /* Function: Initializes resultfile and editfile with temporary filenames
  176.  * in directory dir. Opens resultfile for reading and writing, with fcopy
  177.  * as file descriptor. fedit is set to nil.
  178.  */
  179. {
  180.     editline = 0;    /* make sure we start from the beginning*/
  181.     linecorr = 0;
  182.     editdir = dir;
  183.     resultfile = makedirtemp(dir,1);
  184.     editfile = nil;
  185.         fedit=nil;
  186.     errno = 0;
  187.     return fcopy = fopen(resultfile,"w+");
  188. }
  189.  
  190.     void
  191. inittmpeditfiles()
  192. {
  193.     if (!initeditfiles(tmp()))
  194.         efaterror(resultfile);
  195. }
  196.  
  197.  
  198.     void
  199. arewind(f)
  200.     FILE *f;
  201. {
  202.     if (fseek(f, (long)0, SEEK_SET) == EOF)
  203.         IOerror();
  204. }
  205.  
  206.     void
  207. swapeditfiles(tostdout)
  208.     int tostdout;
  209. /* Function: swaps resultfile and editfile, assigns fedit=fcopy,
  210.  * rewinds fedit for reading, and opens resultfile for reading and
  211.  * writing, using fcopy. If tostdout, fcopy is set to stdout.
  212.  */
  213. {
  214.     const char *tmpptr;
  215.         fedit=fcopy;
  216.     arewind(fedit);
  217.         editline = 1; linecorr=0;
  218.         tmpptr=editfile; editfile=resultfile; resultfile=tmpptr;
  219.         if (tostdout)
  220.                 fcopy=stdout;
  221.     else {
  222.         if (!resultfile)
  223.         resultfile = makedirtemp(editdir,2);
  224.         errno = 0;
  225.         if (!(fcopy = fopen(resultfile,"w+")))
  226.         efaterror(resultfile);
  227.         }
  228. }
  229.  
  230.  
  231.     void
  232. finishedit(delta)
  233.     const struct hshentry *delta;
  234. /* copy the rest of the edit file and close it (if it exists).
  235.  * if delta!=nil, perform keyword substitution at the same time.
  236.  */
  237. {
  238.     register FILE *fe, *fc;
  239.  
  240.     fe = fedit;
  241.     if (fe) {
  242.         fc = fcopy;
  243.